﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Windows;

namespace Moonwish.Core
{
    /// <summary>
    /// View Model基类，by zhlin 2011-08-07
    /// </summary>
    public abstract class NotificationObject<T> : INotifyPropertyChanged, IDataErrorInfo
    {
        /// <summary>
        /// 克隆数据，用于编辑。
        /// </summary>
        /// <returns></returns>
        public abstract T Clone();

        /// <summary>
        /// 覆盖数据。
        /// </summary>
        /// <param name="item"></param>
        public abstract void Override(T item);

        protected Dictionary<string, string> Errors = new Dictionary<string, string>();
        
        /// <summary>
        /// 数据验证方法。
        /// </summary>
        /// <returns></returns>
        public abstract bool Validate();
        /// <summary>
        /// 通知属性改变。
        /// </summary>
        /// <param name="property"></param>
        protected void RaisePropertyChanged(String property)
        {
            var handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }

        protected virtual void RaisePropertyChanged<T1>(Expression<Func<T1>> propertyExpression)
        {
            if (propertyExpression == null)
            {
                return;
            }
            var handler = PropertyChanged;

            if (handler != null)
            {
                var body = propertyExpression.Body as MemberExpression;
                Debug.Assert(body != null, "body != null");
                handler(this, new PropertyChangedEventArgs(body.Member.Name));
            }
        }
        /// <summary>
        /// 属性改变通知事件。
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 实体对象接受改变方法。
        /// </summary>
        public abstract void AcceptChanges();


        public string this[string columnName]
        {
            get
            {
                if (Errors.ContainsKey(columnName))
                {
                    return Errors[columnName];
                }
                return string.Empty;
            }
        }

        protected void SetError(string propertyName, string errorMessage)
        {
            Errors[propertyName] = errorMessage;
            RaisePropertyChanged(propertyName);
        }

        protected void ClearError(string propertyName)
        {
            Errors.Remove(propertyName);
        }

        protected void ClearAllErrors()
        {
            var properties = Errors.Select(error => error.Key).ToList();
            Errors.Clear();
            foreach (string property in properties)
            {
                RaisePropertyChanged(property);
            }
        }

        public string Error
        {
            get { return  null; }
        }

        /// <summary>
        /// 应用按钮可见性
        /// </summary>
        public Visibility ApplyButtonVisibility
        {
            get; set;
        }
    }
}
